class Loadsh{
	constructor(){
		this.timeout = null
		this.timer = null
		this.flag = false
	}
	/**
	 * 函数防抖 (立即执行版)
	 * @param {function} fn 函数
	 * @param {number} delay 延迟执行毫秒数
	 */
	debounceStart (fn, delay = 1000){
		this.debounce(fn,delay,true)
	}
	
	
	/**
	 * 函数防抖 (非立即执行版)
	 * @param {function} fn 函数
	 * @param {number} delay 延迟执行毫秒数
	 */
	debounceEnd  (fn, delay = 1000) {
		this.debounce(fn,delay,false)
	} 
	/**
	 * 函数节流 (立即执行版)
	 * @param {function} fn 函数
	 * @param {number} delay 延迟执行毫秒数
	 */
	throttleStart (fn, delay = 1000){
		this.throttle(fn,delay,true)
	}
	
	
	/**
	 * 函数节流 (非立即执行版)
	 * @param {function} fn 函数
	 * @param {number} delay 延迟执行毫秒数
	 */
	throttleEnd  (fn, delay = 1000) {
		this.throttle(fn,delay,false)
	} 
	
	/**
	 * 防抖原理：一定时间内，只有最后一次操作，再过wait毫秒后才执行函数
	 *
	 * @param {Function} func 要执行的回调函数
	 * @param {Number} wait 延时的时间
	 * @param {Boolean} immediate 是否立即执行
	 * @return null
	 */
	debounce(func, wait = 500, immediate = false){
		var that=this
	    // 清除定时器
	    if (this.timeout !== null) clearTimeout(this.timeout)
	    // 立即执行，此类情况一般用不到
	    if (immediate) {
	        const callNow = !this.timeout
	        this.timeout = setTimeout(() => {
	            that.timeout = null
	        }, wait)
	        if (callNow) typeof func === 'function' && func()
	    } else {
	        // 设置定时器，当最后一次操作后，timeout不会再被清除，所以在延时wait毫秒后执行func回调方法
	        this.timeout = setTimeout(() => {
	            typeof func === 'function' && func()
	        }, wait)
	    }
	}
	/**
	 * 节流原理：在一定时间内，只能触发一次
	 *
	 * @param {Function} func 要执行的回调函数
	 * @param {Number} wait 延时的时间
	 * @param {Boolean} immediate 是否立即执行
	 * @return null
	 */
	throttle(func, wait = 500, immediate = true){
		var that=this
	    if (immediate) {
	        if (!this.flag) {
	            this.flag = true
	            // 如果是立即执行，则在wait毫秒内开始时执行
	            typeof func === 'function' && func()
	            this.timer = setTimeout(() => {
	                that.flag = false
	            }, wait)
	        }
	    } else if (!this.flag) {
	        this.flag = true
	        // 如果是非立即执行，则在wait毫秒内的结束处执行
	        this.timer = setTimeout(() => {
	            that.flag = false
	            typeof func === 'function' && func()
	        }, wait)
	    }
	}
	
}
export default {
	/**
	 * 获取状态机
	 * @param {Array} state 状态列表
	 * @param {Array} trigger 触发器列表
	 * @param {String} 初始状态  
	 */
	getInstance(){
		return new Loadsh()
	}
};